package com.cskaoyan.javase.array._5callby;

/**
 * @description: 值传递和引用传递
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

import java.util.Arrays;

/**
 * 我们在使用方法时,需要给方法传入参数,传入的参数称之为实参。如果方法传入的实参在方法体中被修改了，那么方法结束后，该实参变量的取值会如何变化呢？
 *
 * 值传递(call by value): 值传递意味着实参传递给方法的是，实参的拷贝而不是实参的地址(本身)，那么方法结束后：
 *      实参变量的取值不会随之修改，不变
 *
 * 引用传递(call by reference)： 引用传递意味着实参传递给方法的就是地址(本身)而不是拷贝，那么方法结束后：
 *      实参变量的取值会随之修改，会发生变化
 *
 * 那么Java到底是值传递还是引用传递呢？
 * 写代码做实验来验证
 * 1，我们通过方法1验证得出，至少对于基本数据类型来说，Java是值传递的，因为实参的值没有随着方法修改，方法得到了实参的拷贝
 * 2，我们通过方法2验证得出，对于引用数据类型来说，Java是引用传递的，因为实参的取值随着方法修改了，方法得到了实参的地址
 * 综上，Java是引用传递和值传递都有，基本数据类型是值传递，引用数据类型是引用传递
 *
 * 以上结论大错特错，是典型CSDN博客论调，是不经过思考的低水平“博主”的论调
 *
 * 实际上Java仅存在值传递，不存在引用传递
 *
 *
 */
public class Demo {
    public static void main(String[] args) {
        /*int a = 10;
        doubleIntValue(a);
        System.out.println(a);*/

        /*int[] arr = {1, 2, 3};
        doubleArrayValue(arr);
        System.out.println(Arrays.toString(arr));*/

        int[] arr = {666, 777, 888};
        int[] arr2 = {111, 222, 333};
        System.out.println("交换前arr"+Arrays.toString(arr));
        System.out.println("交换前arr2"+Arrays.toString(arr2));
        swap(arr, arr2);
        System.out.println("交换后arr"+Arrays.toString(arr));
        System.out.println("交换后arr2"+Arrays.toString(arr2));
        /**
         * 请思考:
         *  1,如果java是值传递,能否交换成功?
         *  2,如果java是引用传递,能否交换成功?
         */

    }

    //1，方法把传入的int类型参数变为它原先的2倍（基本数据类型）
    public static void doubleIntValue(int a) {
        a *= 2;
    }

    //2，方法把传入的数组变量的元素变为它原先的2倍（引用数据类型）
    public static void doubleArrayValue(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
    }

    //3，交换两个数组对象的引用
    public static void swap(int[] arr, int[] arr2) {
        int[] temp = arr;
        arr = arr2;
        arr2 = temp;

        System.out.println("交换中arr"+Arrays.toString(arr));
        System.out.println("交换中arr2"+Arrays.toString(arr2));
    }

}
